class Tetris {
    constructor() {
        this.canvas = document.getElementById('game-canvas');
        this.nextCanvas = document.getElementById('next-piece');
        this.ctx = this.canvas.getContext('2d');
        this.nextCtx = this.nextCanvas.getContext('2d');

        // 修改画布大小
        this.canvas.width = 250;  // 从 300 改为 250
        this.canvas.height = 500; // 从 600 改为 500
        this.nextCanvas.width = 100;
        this.nextCanvas.height = 100;

        // 相应调整方块大小
        this.blockSize = 25;  // 从 30 改为 25
        this.cols = 10;
        this.rows = 20;
        this.score = 0;

        // 方块形状定义
        this.shapes = [
            [[1, 1, 1, 1]], // I
            [[1, 1, 1], [0, 1, 0]], // T
            [[1, 1, 1], [1, 0, 0]], // L
            [[1, 1, 1], [0, 0, 1]], // J
            [[1, 1], [1, 1]], // O
            [[1, 1, 0], [0, 1, 1]], // Z
            [[0, 1, 1], [1, 1, 0]] // S
        ];

        // 添加方块颜色定义
        this.colors = [
            '#FF0D72',  // I 方块 - 红色
            '#0DC2FF',  // T 方块 - 蓝色
            '#0DFF72',  // L 方块 - 绿色
            '#F538FF',  // J 方块 - 紫色
            '#FFE138',  // O 方块 - 黄色
            '#FF8E0D',  // Z 方块 - 橙色
            '#3877FF'   // S 方块 - 蓝色
        ];

        // 添加动画相关属性
        this.clearingLines = [];
        this.clearAnimationFrame = 0;
        this.clearAnimationDuration = 10; // 动画帧数

        // 添加速度相关配置
        this.initialInterval = 1000;  // 初始下落间隔（毫秒）
        this.minInterval = 100;       // 最小下落间隔（毫秒）
        this.speedIncrease = 50;      // 每次加速减少的毫秒数
        this.speedUpScore = 500;      // 每得多少分加速一次
        this.dropInterval = this.initialInterval;

        // 添加游戏结束相关属性
        this.gameOver = false;
        this.gameOverAlpha = 0;  // 用于游戏结束渐变效果

        // 添加按键状态
        this.keyStates = {
            left: false,
            right: false,
            down: false,
            up: false
        };

        // 添加按键延迟配置
        this.keyDelay = 100;  // 按键延迟（毫秒）
        this.lastKeyTime = {
            left: 0,
            right: 0,
            down: 0,
            up: 0
        };

        this.init();
    }

    init() {
        // 重置所有游戏状态
        this.board = Array(this.rows).fill().map(() => Array(this.cols).fill(0));
        this.gameOver = false;
        this.gameOverAlpha = 0;
        this.score = 0;
        this.dropInterval = this.initialInterval;
        document.getElementById('score-value').textContent = '0';

        // 生成初始方块
        this.currentPiece = this.generatePiece();
        this.nextPiece = this.generatePiece();

        this.lastDrop = Date.now();

        // 修改事件监听
        document.addEventListener('keydown', this.handleKeyDown.bind(this));
        document.addEventListener('keyup', this.handleKeyUp.bind(this));

        // 开始游戏循环
        requestAnimationFrame(this.gameLoop.bind(this));
    }

    generatePiece() {
        const shapeIndex = Math.floor(Math.random() * this.shapes.length);
        const shape = this.shapes[shapeIndex];
        const piece = {
            shape,
            x: Math.floor(this.cols / 2) - Math.floor(shape[0].length / 2),
            y: 0,
            color: this.colors[shapeIndex]
        };

        return piece;  // 直接返回新生成的方块，不设置 currentPiece
    }

    handleKeyDown(event) {
        if (this.gameOver) {
            if (event.keyCode === 32) { // 空格键
                this.init();
            }
            return;
        }

        const now = Date.now();

        switch (event.keyCode) {
            case 37: // 左
                if (!this.keyStates.left && now - this.lastKeyTime.left > this.keyDelay) {
                    if (this.isValidMove(this.currentPiece.x - 1, this.currentPiece.y, this.currentPiece.shape)) {
                        this.currentPiece.x--;
                    }
                    this.keyStates.left = true;
                    this.lastKeyTime.left = now;
                }
                break;
            case 39: // 右
                if (!this.keyStates.right && now - this.lastKeyTime.right > this.keyDelay) {
                    if (this.isValidMove(this.currentPiece.x + 1, this.currentPiece.y, this.currentPiece.shape)) {
                        this.currentPiece.x++;
                    }
                    this.keyStates.right = true;
                    this.lastKeyTime.right = now;
                }
                break;
            case 40: // 下
                if (!this.keyStates.down && now - this.lastKeyTime.down > this.keyDelay) {
                    this.hardDrop();
                    this.keyStates.down = true;
                    this.lastKeyTime.down = now;
                }
                break;
            case 38: // 上 (旋转)
                if (!this.keyStates.up && now - this.lastKeyTime.up > this.keyDelay) {
                    const rotated = this.rotate(this.currentPiece.shape);
                    if (this.isValidMove(this.currentPiece.x, this.currentPiece.y, rotated)) {
                        this.currentPiece.shape = rotated;
                    }
                    this.keyStates.up = true;
                    this.lastKeyTime.up = now;
                }
                break;
        }
    }

    handleKeyUp(event) {
        switch (event.keyCode) {
            case 37: // 左
                this.keyStates.left = false;
                break;
            case 39: // 右
                this.keyStates.right = false;
                break;
            case 40: // 下
                this.keyStates.down = false;
                break;
            case 38: // 上
                this.keyStates.up = false;
                break;
        }
    }

    rotate(shape) {
        const newShape = Array(shape[0].length).fill().map(() => Array(shape.length).fill(0));
        for (let y = 0; y < shape.length; y++) {
            for (let x = 0; x < shape[y].length; x++) {
                newShape[x][shape.length - 1 - y] = shape[y][x];
            }
        }
        return newShape;
    }

    isValidMove(x, y, shape) {
        for (let row = 0; row < shape.length; row++) {
            for (let col = 0; col < shape[row].length; col++) {
                if (shape[row][col]) {
                    const newX = x + col;
                    const newY = y + row;

                    if (newX < 0 || newX >= this.cols || newY >= this.rows) {
                        return false;
                    }

                    if (newY >= 0 && this.board[newY][newX]) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    mergePiece() {
        for (let row = 0; row < this.currentPiece.shape.length; row++) {
            for (let col = 0; col < this.currentPiece.shape[row].length; col++) {
                if (this.currentPiece.shape[row][col]) {
                    const boardY = this.currentPiece.y + row;
                    // 修改游戏结束判定：如果方块超出顶部，游戏结束
                    if (boardY < 0) {
                        this.gameOver = true;
                        return;
                    }
                    this.board[boardY][this.currentPiece.x + col] = this.currentPiece.color;
                }
            }
        }

        // 在合并方块后立即检查是否有可消除的行
        this.clearLines();
    }

    clearLines() {
        let linesToClear = [];

        // 从底部向上检查每一行
        for (let row = this.rows - 1; row >= 0; row--) {
            let isFull = true;
            // 检查这一行的每个格子
            for (let col = 0; col < this.cols; col++) {
                if (!this.board[row][col]) {
                    isFull = false;
                    break;
                }
            }
            if (isFull) {
                linesToClear.push(row);
            }
        }

        if (linesToClear.length > 0) {
            // 开始清除动画
            this.clearingLines = linesToClear;
            this.clearAnimationFrame = 0;
            this.animateClearLines();
        } else if (!this.gameOver) {
            // 如果没有行需要清除，且游戏未结束，生成新方块
            this.currentPiece = this.nextPiece;
            this.nextPiece = this.generatePiece();
            this.lastDrop = Date.now();  // 添加这行以重置下落计时

            // 检查新方块是否可以放置，如果不能则游戏结束
            if (!this.isValidMove(this.currentPiece.x, this.currentPiece.y, this.currentPiece.shape)) {
                this.gameOver = true;
            }
        }
    }

    animateClearLines() {
        if (this.clearAnimationFrame >= this.clearAnimationDuration) {
            // 动画结束，实际清除行
            this.finishClearLines();
            return;
        }

        this.clearAnimationFrame++;
        // 继续动画
        requestAnimationFrame(this.animateClearLines.bind(this));
    }

    finishClearLines() {
        // 按从下到上的顺序清除行
        this.clearingLines.sort((a, b) => b - a);

        // 清除行并更新分数
        for (let row of this.clearingLines) {
            // 删除已满的行
            this.board.splice(row, 1);
            // 在顶部添加新的空行
            this.board.unshift(Array(this.cols).fill(0));
        }

        // 更新分数
        this.updateScore(this.clearingLines.length);

        // 重置清除动画状态
        this.clearingLines = [];
        this.clearAnimationFrame = 0;

        // 生成新方块
        if (!this.gameOver) {
            this.currentPiece = this.nextPiece;
            this.nextPiece = this.generatePiece();

            // 检查新方块是否可以放置，如果不能则游戏结束
            if (!this.isValidMove(this.currentPiece.x, this.currentPiece.y, this.currentPiece.shape)) {
                this.gameOver = true;
            }
        }
    }

    draw() {
        // 清空画布
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.nextCtx.clearRect(0, 0, this.nextCanvas.width, this.nextCanvas.height);

        // 绘制游戏板
        for (let row = 0; row < this.rows; row++) {
            for (let col = 0; col < this.cols; col++) {
                if (this.board[row][col]) {
                    // 如果当前行正在清除动画中，添加闪烁效果
                    if (this.clearingLines.includes(row)) {
                        const alpha = Math.abs(Math.sin(this.clearAnimationFrame * 0.5));
                        this.drawBlock(
                            this.ctx,
                            col,
                            row,
                            this.board[row][col],
                            false,
                            alpha
                        );
                    } else {
                        this.drawBlock(this.ctx, col, row, this.board[row][col]);
                    }
                }
            }
        }

        // 绘制当前方块的影子
        if (!this.gameOver && this.currentPiece) {
            const shadowPiece = {
                ...this.currentPiece,
                y: this.currentPiece.y
            };

            // 找到影子的最终位置
            while (this.isValidMove(shadowPiece.x, shadowPiece.y + 1, shadowPiece.shape)) {
                shadowPiece.y++;
            }

            // 只有当影子位置与当前方块位置不同时才绘制影子
            if (shadowPiece.y !== this.currentPiece.y) {
                this.drawPiece(this.ctx, shadowPiece, false, true);
            }
        }

        // 绘制当前方块
        if (!this.gameOver) {
            this.drawPiece(this.ctx, this.currentPiece);

            // 修改这里：绘制下一个方块的预览
            const nextPiecePreview = {
                shape: this.nextPiece.shape,
                x: Math.floor((5 - this.nextPiece.shape[0].length) / 2),
                y: Math.floor((5 - this.nextPiece.shape.length) / 2),
                color: this.nextPiece.color
            };
            this.drawPiece(this.nextCtx, nextPiecePreview, true);
        }

        if (this.gameOver) {
            // 游戏结束渐变效果
            this.gameOverAlpha = Math.min(0.8, this.gameOverAlpha + 0.02);
            this.ctx.fillStyle = `rgba(0, 0, 0, ${this.gameOverAlpha})`;
            this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

            if (this.gameOverAlpha >= 0.5) {
                // 添加文字阴影效果
                this.ctx.shadowColor = '#a3b1c6';
                this.ctx.shadowBlur = 10;
                this.ctx.shadowOffsetX = 2;
                this.ctx.shadowOffsetY = 2;

                // 显示游戏结束文字
                this.ctx.fillStyle = '#e0e5ec';
                this.ctx.font = '30px Arial';
                this.ctx.textAlign = 'center';
                this.ctx.fillText('游戏结束', this.canvas.width / 2, this.canvas.height / 2 - 30);

                // 显示最终分数
                this.ctx.font = '20px Arial';
                this.ctx.fillText(`最终分数: ${this.score}`, this.canvas.width / 2, this.canvas.height / 2 + 10);

                // 显示重新开始提示
                this.ctx.font = '16px Arial';
                this.ctx.fillText('按空格键重新开始', this.canvas.width / 2, this.canvas.height / 2 + 40);

                // 重置阴影
                this.ctx.shadowColor = 'transparent';
                this.ctx.shadowBlur = 0;
                this.ctx.shadowOffsetX = 0;
                this.ctx.shadowOffsetY = 0;
            }
        }
    }

    drawBlock(ctx, x, y, color, isPreview = false, alpha = 1) {
        const size = isPreview ? 20 : this.blockSize;
        const padding = 2;
        const radius = 4;

        // 设置透明度
        ctx.globalAlpha = alpha;

        // 计算实际绘制位置和大小
        const blockX = x * size + padding;
        const blockY = y * size + padding;
        const blockSize = size - padding * 2;

        // 创建圆角矩形路径
        ctx.beginPath();
        ctx.moveTo(blockX + radius, blockY);
        ctx.lineTo(blockX + blockSize - radius, blockY);
        ctx.quadraticCurveTo(blockX + blockSize, blockY, blockX + blockSize, blockY + radius);
        ctx.lineTo(blockX + blockSize, blockY + blockSize - radius);
        ctx.quadraticCurveTo(blockX + blockSize, blockY + blockSize, blockX + blockSize - radius, blockY + blockSize);
        ctx.lineTo(blockX + radius, blockY + blockSize);
        ctx.quadraticCurveTo(blockX, blockY + blockSize, blockX, blockY + blockSize - radius);
        ctx.lineTo(blockX, blockY + radius);
        ctx.quadraticCurveTo(blockX, blockY, blockX + radius, blockY);
        ctx.closePath();

        // 绘制外部阴影（凸起效果）
        ctx.shadowColor = 'rgba(0, 0, 0, 0.2)';
        ctx.shadowBlur = 4;
        ctx.shadowOffsetX = 2;
        ctx.shadowOffsetY = 2;

        // 绘制方块底色
        ctx.fillStyle = color;
        ctx.fill();

        // 重置阴影
        ctx.shadowColor = 'transparent';
        ctx.shadowBlur = 0;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 0;

        // 绘制顶部高光（凸起效果）
        const lightGradient = ctx.createLinearGradient(
            blockX, blockY,
            blockX, blockY + blockSize
        );
        lightGradient.addColorStop(0, 'rgba(255, 255, 255, 0.8)');
        lightGradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.2)');
        lightGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');

        ctx.fillStyle = lightGradient;
        ctx.fill();

        // 绘制左侧高光
        const leftGradient = ctx.createLinearGradient(
            blockX, blockY,
            blockX + blockSize * 0.5, blockY
        );
        leftGradient.addColorStop(0, 'rgba(255, 255, 255, 0.4)');
        leftGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');

        ctx.fillStyle = leftGradient;
        ctx.fill();

        // 绘制边缘
        ctx.strokeStyle = color;
        ctx.lineWidth = 1;
        ctx.stroke();

        // 重置透明度
        ctx.globalAlpha = 1;

        // 如果是影子，简化绘制效果
        if (alpha < 1) {
            // 只绘制轮廓
            ctx.strokeStyle = color;
            ctx.lineWidth = 2;
            ctx.stroke();

            // 重置透明度
            ctx.globalAlpha = 1;
            return;
        }
    }

    drawPiece(ctx, piece, isPreview = false, isShadow = false) {
        for (let row = 0; row < piece.shape.length; row++) {
            for (let col = 0; col < piece.shape[row].length; col++) {
                if (piece.shape[row][col]) {
                    this.drawBlock(
                        ctx,
                        piece.x + col,
                        piece.y + row,
                        piece.color,
                        isPreview,
                        isShadow ? 0.08 : 1  // 将影子透明度从 0.2 降低到 0.08
                    );
                }
            }
        }
    }

    gameLoop() {
        const now = Date.now();
        if (!this.gameOver && now - this.lastDrop > this.dropInterval) {
            if (this.isValidMove(this.currentPiece.x, this.currentPiece.y + 1, this.currentPiece.shape)) {
                this.currentPiece.y++;
                this.lastDrop = now;
            } else {
                this.mergePiece();
            }
        }

        this.draw();
        requestAnimationFrame(this.gameLoop.bind(this));
    }

    // 添加硬降方法
    hardDrop() {
        while (this.isValidMove(this.currentPiece.x, this.currentPiece.y + 1, this.currentPiece.shape)) {
            this.currentPiece.y++;
        }
        this.mergePiece();
    }

    // 修改更新分数的逻辑
    updateScore(clearedLines) {
        const oldScore = this.score;
        this.score += clearedLines * 100;
        document.getElementById('score-value').textContent = this.score;

        // 检查是否需要加速
        const oldLevel = Math.floor(oldScore / this.speedUpScore);
        const newLevel = Math.floor(this.score / this.speedUpScore);

        if (newLevel > oldLevel) {
            this.increaseSpeed();
        }
    }

    // 添加加速方法
    increaseSpeed() {
        this.dropInterval = Math.max(
            this.minInterval,
            this.dropInterval - this.speedIncrease
        );
    }

    // 添加游戏结束检查方法
    checkGameOver() {
        // 检查新生成的方块是否有重叠
        for (let row = 0; row < this.currentPiece.shape.length; row++) {
            for (let col = 0; col < this.currentPiece.shape[row].length; col++) {
                if (this.currentPiece.shape[row][col]) {
                    const boardY = this.currentPiece.y + row;
                    const boardX = this.currentPiece.x + col;
                    if (boardY >= 0 && this.board[boardY][boardX]) {
                        this.gameOver = true;
                        return true;
                    }
                }
            }
        }
        return false;
    }
}

// 启动游戏
window.onload = () => {
    new Tetris();
}; 